/**
 * 数据字典vuex模块
 */
import Vue from 'vue';
import {
  util,
  cacheUtil
} from 'utils/util';

const state = _dict_local || {
  dict: {}
};
try {
  if (_dict_cache && _dict_cache.dict) {
    for (var key in _dict_cache.dict) {
      state.dict[key] = _dict_cache.dict[key];
    }
  }
} catch (error) {
  console.error('_dict_cache 错误，from dictStore.js 20行');
}
// 将静态下拉框数据存入cache
for (const key in state.dict) {
  cacheUtil.setDict(key, {}, state.dict[key]);
}

const isFunction = function(value) {
  return Object.prototype.toString.call(value) === '[object Function]';
};

/** **********************************************
 *         相同时间内同一请求不重复触发           *
 ************************************************/
const loadWaitStack = [];
// 校验两个对象是否相同
const isObjectValueEqual = function(a, b) {
  var aProps = Object.getOwnPropertyNames(a);
  var bProps = Object.getOwnPropertyNames(b);
  if (aProps.length !== bProps.length) {
    return false;
  }
  for (var i = 0; i < aProps.length; i++) {
    var propName = aProps[i];
    var propA = a[propName];
    var propB = b[propName];
    // 先判断两边都有相同键名
    if (!b.hasOwnProperty(propName)) return false;
    if ((propA instanceof Object)) {
      if (!isObjectValueEqual(propA, propB)) {
        return false;
      }
    } else if (propA !== propB) {
      return false;
    }
  }
  return true;
};
// 检查loadWaitStack是否存在该请求
const checkStack = function(data, params) {
  var index = -1;
  for (var i = 0; i < loadWaitStack.length; i++) {
    // 判断请求是否已存在
    if (isObjectValueEqual(loadWaitStack[i].data, data)) {
      index = i;
      break;
    }
  }
  // 不存在则新增
  if (index !== -1) {
    loadWaitStack[index].payloadArr.push(params);
    return true;
  } else {
    loadWaitStack.push({
      data: data,
      payloadArr: [params]
    });
    return false;
  }
};

// 加载请求完成
const loadDataComplate = function(data, type, resq) {
  for (var i = 0; i < loadWaitStack.length; i++) {
    // 判断请求是否已存在
    if (isObjectValueEqual(loadWaitStack[i].data, data)) {
      if (type === 'success') {
        loadWaitStack[i].payloadArr.forEach(function(ite) {
          var payload = ite.payload;
          var cacheable = ite.cacheable;
          var commit = ite.commit;
          var dictId = ite.dictId;
          var dictParams = ite.dictParams;
          if (resq.data) {
            payload['dictData'] = resq.data;
            if (!payload.dictFilter) { // 普通翻译提交到vuex缓存
              cacheable && cacheUtil.setDict(dictId, dictParams, resq.data);
              commit('updateDict', payload); // commit提交数据
            } else { // 机构等大数据量翻译 提交到localstorage缓存
              var tmp = [];
              payload['dictData'].forEach(function(item) {
                cacheUtil.setDictText(dictId, item.c_code, item.c_cname);
                tmp.push(item.c_code);
              });
              if (dictParams.filter_codes) {
                dictParams.filter_codes.forEach((code) => {
                  if (tmp.indexOf(code) === -1) { // 没有取得翻译结果，原值返回
                    cacheUtil.setDictText(dictId, code, code, 10); // 没查询到的只缓存10秒，防止表格翻译时进入死循环，防止长期缓存导致取不到正常结果
                    console.warn('无法翻译下拉框，dictId=' + dictId + '，code=' + code);
                  }
                });
              }
            }
            isFunction(payload.successCallback) && payload.successCallback(payload); // 成功时回调
          } else {
            isFunction(payload.errorCallback) && payload.errorCallback(payload);
          }
        });
      } else if (type === 'error') {
        loadWaitStack[i].payloadArr.forEach(function(ite) {
          var payload = ite.payload;
          isFunction(payload.errorCallback) && payload.errorCallback(payload);
        });
      }
      // 移除
      loadWaitStack.splice(i, 1);
      break;
    }
  }
};

/** ********************************/

const actions = {
  /**
   * 从后台加载数据字典
   */
  loadDict({
    commit,
    state
  }, payload) {
    const dictId = payload.dictId;
    const dictParams = payload.dictParams;
    const cacheable = payload.cacheable === undefined ? true : payload.cacheable;
    const dictData = cacheUtil.getDict(dictId, dictParams);
    if (dictData && dictData.length > 0 && cacheable) { // 字典已存在cache中，且允许缓存
      payload['dictData'] = dictData;
      commit('updateDict', payload); // commit提交数据
      isFunction(payload.successCallback) && payload.successCallback(payload); // 成功时回调
      return;
    }

    var codelistIds = {
      id: dictId,
      param: dictParams
    };

    var keyObj = JSON.parse(JSON.stringify(codelistIds));
    if (checkStack(keyObj, {
      payload: payload,
      cacheable: cacheable,
      commit: commit,
      dictId: dictId,
      dictParams: dictParams
    })) return;

    // 请求远程数据字典
    util.request({
      serviceId: 'SYS00002',
      tranCode: 'SYS0000002',
      pageNo: 1,
      pageSize: 100,
      // model: {},
      async: true,
      showLoading: false,
      model: codelistIds,
      onSuccess: function(jqXHR, textStatus, resq) {
        loadDataComplate(keyObj, 'success', resq);
        /* if ( resq.data ) {
            payload['dictData'] = resq.data;
            if(!payload.dictFilter){//普通翻译提交到vuex缓存
                cacheable && cacheUtil.setDict(dictId, dictParams, resq.data);
                commit('updateDict', payload); //commit提交数据
            }else{ //机构等大数据量翻译 提交到localstorage缓存
                let tmp=[];
                payload['dictData'].forEach(function (item) {
                    cacheUtil.setDictText(dictId,item.c_code,item.c_cname);
                    tmp.push(item.c_code);
                });
                if(dictParams.filter_codes){
                   dictParams.filter_codes.forEach((code)=>{
                        if(tmp.indexOf(code)==-1){ //没有取得翻译结果，原值返回
                             cacheUtil.setDictText(dictId,code,code,10);   //没查询到的只缓存10秒，防止表格翻译时进入死循环，防止长期缓存导致取不到正常结果
                             console.warn('无法翻译下拉框，dictId='+dictId+'，code='+code);
                        }
                   })
                }
            }
            isFunction(payload.successCallback) && payload.successCallback(payload); //成功时回调
        }else{
            isFunction(payload.errorCallback) && payload.errorCallback(payload);
        }*/
      },
      onError: function() { // 失败时回调
        loadDataComplate(keyObj, 'error');
        // isFunction(payload.errorCallback) && payload.errorCallback(payload);
      }
    });
  }
};

const mutations = {
  /**
   * 通知vuex更新数据字典
   */
  updateDict(state, payload) {
    Vue.set(state.dict, payload.dictId, payload.dictData); // 动态追加属性
  }
};

const getters = {
  // 数据字典
  getDict: (state, getters) => {
    return state.dict;
  }
};

export default {
  state,
  actions,
  mutations,
  getters
};
